home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / progjour / 1987 / 06 / sample.asm < prev    next >
Assembly Source File  |  1987-10-12  |  14KB  |  528 lines

  1. ; Sample EGA program.
  2. ; Animates four balls bouncing around a playfield by using
  3. ; page flipping. Playfield is panned smoothly both horizontally
  4. ; and vertically.
  5. ; Assembled with MASM 4.0, linked with LINK 3.51.
  6. ; Copyright by Michael Abrash, 11/2/86.
  7. ;
  8. stack    segment    para stack 'STACK'
  9.     db    512 dup(?)
  10. stack    ends
  11. ;
  12. HIRES_VIDEO_MODE    equ    0    ;define for 640x350 video mode
  13.                     ; comment out for 640x200 mode
  14. VIDEO_SEGMENT    equ    0a000h        ;display memory segment for
  15.                     ; true EGA graphics modes
  16. LOGICAL_SCREEN_WIDTH    equ    672/8    ;width in bytes and height in scan
  17. LOGICAL_SCREEN_HEIGHT    equ    384    ; lines of the virtual screen
  18.                     ; we'll work with
  19. PAGE0        equ    0    ;flag for page 0 when page flipping
  20. PAGE1        equ    1    ;flag for page 1 when page flipping
  21. PAGE0_OFFSET    equ    0    ;start offset of page 0 in EGA memory
  22. PAGE1_OFFSET    equ    LOGICAL_SCREEN_WIDTH * LOGICAL_SCREEN_HEIGHT
  23.                 ;start offset of page 1 (both pages
  24.                 ; are 672x384 virtual screens)
  25. BALL_WIDTH    equ    24/8    ;width of ball in display memory bytes
  26. BALL_HEIGHT    equ    24    ;height of ball in scan lines
  27. BLANK_OFFSET    equ    PAGE1_OFFSET * 2    ;start of blank image
  28.                         ; in EGA memory
  29. BALL_OFFSET    equ    BLANK_OFFSET + (BALL_WIDTH * BALL_HEIGHT)
  30.                 ;start offset of ball image in EGA memory
  31. NUM_BALLS    equ    4    ;number of balls to animate
  32. ;
  33. ; EGA register equates.
  34. ;
  35. TS_INDEX    equ    3c4h    ;TS index register
  36. MAP_MASK    equ    2    ;TS map mask register
  37. GDC_INDEX    equ    3ceh    ;GDC index register
  38. GDC_MODE    equ    5    ;GDC mode register
  39. CRTC_INDEX    equ    03d4h    ;CRTC index register
  40. START_ADDRESS_HIGH equ    0ch    ;CRTC start address high byte
  41. START_ADDRESS_LOW equ    0dh    ;CRTC start address low byte
  42. CRTC_OFFSET    equ    13h    ;CRTC offset register
  43. STATUS_REGISTER_1 equ    03dah    ;EGA status register
  44. VSYNC_MASK    equ    08h    ;vertical sync bit in status register 1
  45. ATC_INDEX    equ    03c0h    ;ATC index register
  46. HPELPAN        equ    20h OR 13h    ;ATC horizontal pel panning register
  47.                     ; (bit 7 is high to keep palette RAM
  48.                     ; addressing on)
  49. dseg    segment    para common 'DATA'
  50. CurrentPage        db    PAGE1        ;page to draw to
  51. CurrentPageOffset    dw    PAGE1_OFFSET
  52. ;
  53. ; Four plane's worth of multicolored ball image.
  54. ;
  55. BallPlane0Image    label    byte        ;blue plane image
  56.     db    000h, 03ch, 000h, 001h, 0ffh, 080h
  57.     db    007h, 0ffh, 0e0h, 00fh, 0ffh, 0f0h
  58.     db    4 * 3 dup(000h)
  59.     db    07fh, 0ffh, 0feh, 0ffh, 0ffh, 0ffh
  60.     db    0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
  61.     db    4 * 3 dup(000h)
  62.     db    07fh, 0ffh, 0feh, 03fh, 0ffh, 0fch
  63.     db    03fh, 0ffh, 0fch, 01fh, 0ffh, 0f8h
  64.     db    4 * 3 dup(000h)
  65. BallPlane1Image    label    byte        ;green plane image
  66.     db    4 * 3 dup(000h)
  67.     db    01fh, 0ffh, 0f8h, 03fh, 0ffh, 0fch
  68.     db    03fh, 0ffh, 0fch, 07fh, 0ffh, 0feh
  69.     db    07fh, 0ffh, 0feh, 0ffh, 0ffh, 0ffh
  70.     db    0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
  71.     db    8 * 3 dup(000h)
  72.     db    00fh, 0ffh, 0f0h, 007h, 0ffh, 0e0h
  73.     db    001h, 0ffh, 080h, 000h, 03ch, 000h
  74. BallPlane2Image    label    byte        ;red plane image
  75.     db    12 * 3 dup(000h)
  76.     db    0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
  77.     db    0ffh, 0ffh, 0ffh, 07fh, 0ffh, 0feh
  78.     db    07fh, 0ffh, 0feh, 03fh, 0ffh, 0fch
  79.     db    03fh, 0ffh, 0fch, 01fh, 0ffh, 0f8h
  80.     db    00fh, 0ffh, 0f0h, 007h, 0ffh, 0e0h
  81.     db    001h, 0ffh, 080h, 000h, 03ch, 000h
  82. BallPlane3Image    label    byte        ;intensity on for all planes,
  83.                     ; to produce high-intensity colors
  84.     db    000h, 03ch, 000h, 001h, 0ffh, 080h
  85.     db    007h, 0ffh, 0e0h, 00fh, 0ffh, 0f0h
  86.     db    01fh, 0ffh, 0f8h, 03fh, 0ffh, 0fch
  87.     db    03fh, 0ffh, 0fch, 07fh, 0ffh, 0feh
  88.     db    07fh, 0ffh, 0feh, 0ffh, 0ffh, 0ffh
  89.     db    0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
  90.     db    0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
  91.     db    0ffh, 0ffh, 0ffh, 07fh, 0ffh, 0feh
  92.     db    07fh, 0ffh, 0feh, 03fh, 0ffh, 0fch
  93.     db    03fh, 0ffh, 0fch, 01fh, 0ffh, 0f8h
  94.     db    00fh, 0ffh, 0f0h, 007h, 0ffh, 0e0h
  95.     db    001h, 0ffh, 080h, 000h, 03ch, 000h
  96. ;
  97. BallX        dw    15, 50, 40, 70        ;array of ball x coords
  98. BallY        dw    40, 200, 110, 300    ;array of ball y coords
  99. LastBallX    dw    15, 50, 40, 70        ;previous ball x coords
  100. LastBallY    dw    40, 100, 160, 30    ;previous ball y coords
  101. BallXInc    dw    1, 1, 1, 1        ;x move factors for ball
  102. BallYInc    dw    8, 8, 8, 8        ;y move factors for ball
  103. BallRep        dw    1, 1, 1, 1        ;# times to keep moving
  104.                         ; ball according to current
  105.                         ; increments
  106. BallControl    dw    Ball0Control, Ball1Control    ;pointers to current
  107.         dw    Ball2Control, Ball3Control    ; locations in ball
  108.                             ; control strings
  109. BallControlString    dw    Ball0Control, Ball1Control ;pointers to
  110.             dw    Ball2Control, Ball3Control ; start of ball
  111.                                ; control strings
  112. ;
  113. ; Ball control strings.
  114. ;
  115. Ball0Control    label    word
  116.     dw    10, 1, 4, 10, -1, 4, 10, -1, -4, 10, 1, -4, 0
  117. Ball1Control    label    word
  118.     dw    12, -1, 1, 28, -1, -1, 12, 1, -1, 28, 1, 1, 0
  119. Ball2Control    label    word
  120.     dw    20, 0, -1, 40, 0, 1, 20, 0, -1, 0
  121. Ball3Control    label    word
  122.     dw    8, 1, 0, 52, -1, 0, 44, 1, 0, 0
  123. ;
  124. ; Panning control string.
  125. ;
  126. ifdef HIRES_VIDEO_MODE
  127. PanningControlString    dw    32, 1, 0, 34, 0, 1, 32, -1, 0, 34, 0, -1, 0
  128. else
  129. PanningControlString    dw    32, 1, 0, 184, 0, 1, 32, -1, 0, 184, 0, -1, 0
  130. endif
  131. PanningControl    dw    PanningControlString    ;pointer to current location
  132.                         ; in panning control string
  133. PanningRep    dw    1    ;# times to pan according to current
  134.                 ; panning increments
  135. PanningXInc    dw    1    ;x panning factor
  136. PanningYInc    dw    0    ;y panning factor
  137. HPan        db    0    ;horizontal pel panning setting
  138. PanningStartOffset dw    0    ;start offset adjustment to produce vertical
  139.                 ; panning & coarse horizontal panning
  140. dseg    ends
  141. ;
  142. ; Macro to set indexed register P2 of chip with index register
  143. ; at P1 to AL.
  144. ;
  145. SETREG    macro    P1, P2
  146.     mov    dx,P1
  147.     mov    ah,al
  148.     mov    al,P2
  149.     out    dx,ax
  150.     endm
  151. ;
  152. cseg    segment    para public 'CODE'
  153.     assume    cs:cseg, ds:dseg
  154. start    proc    near
  155.     mov    ax,dseg
  156.     mov    ds,ax
  157. ;
  158. ; Select graphics mode.
  159. ;
  160. ifdef HIRES_VIDEO_MODE
  161.     mov    ax,010h
  162. else
  163.     mov    ax,0eh
  164. endif
  165.     int    10h
  166. ;
  167. ; ES always points to EGA memory.
  168. ;
  169.     mov    ax,VIDEO_SEGMENT
  170.     mov    es,ax
  171. ;
  172. ; Draw border around playfield in both pages.
  173. ;
  174.     mov    di,PAGE0_OFFSET
  175.     call    DrawBorder    ;page 0 border
  176.     mov    di,PAGE1_OFFSET
  177.     call    DrawBorder    ;page 1 border
  178. ;
  179. ; Draw all four plane's worth of the ball to undisplayed EGA memory.
  180. ;
  181.     mov    al,01h        ;enable plane 0
  182.     SETREG    TS_INDEX, MAP_MASK
  183.     mov    si,offset BallPlane0Image
  184.     mov    di,BALL_OFFSET
  185.     mov    cx,BALL_WIDTH * BALL_HEIGHT
  186.     rep movsb
  187.     mov    al,02h        ;enable plane 1
  188.     SETREG    TS_INDEX, MAP_MASK
  189.     mov    si,offset BallPlane1Image
  190.     mov    di,BALL_OFFSET
  191.     mov    cx,BALL_WIDTH * BALL_HEIGHT
  192.     rep movsb
  193.     mov    al,04h        ;enable plane 2
  194.     SETREG    TS_INDEX, MAP_MASK
  195.     mov    si,offset BallPlane2Image
  196.     mov    di,BALL_OFFSET
  197.     mov    cx,BALL_WIDTH * BALL_HEIGHT
  198.     rep movsb
  199.     mov    al,08h        ;enable plane 3
  200.     SETREG    TS_INDEX, MAP_MASK
  201.     mov    si,offset BallPlane3Image
  202.     mov    di,BALL_OFFSET
  203.     mov    cx,BALL_WIDTH * BALL_HEIGHT
  204.     rep movsb
  205. ;
  206. ; Draw a blank image the size of the ball to undisplayed EGA memory.
  207. ;
  208.     mov    al,0fh            ;enable all memory planes, since the
  209.     SETREG    TS_INDEX, MAP_MASK    ; blank has to erase all planes
  210.     mov    di,BLANK_OFFSET
  211.     mov    cx,BALL_WIDTH * BALL_HEIGHT
  212.     sub    al,al
  213.     rep stosb
  214. ;
  215. ; Set EGA to write mode 1, for block copying ball and blank images.
  216. ;
  217.     mov    al,1
  218.     SETREG    GDC_INDEX, GDC_MODE
  219. ;
  220. ; Set EGA offset register in words to define logical screen width.
  221. ;
  222.     mov    al,LOGICAL_SCREEN_WIDTH / 2
  223.     SETREG    CRTC_INDEX, CRTC_OFFSET
  224. ;
  225. ; Move the balls by erasing each ball, moving it, and
  226. ; redrawing it, then switching pages when they're all moved.
  227. ;
  228. BallAnimationLoop:
  229.     mov    bx,( NUM_BALLS * 2 ) - 2
  230. EachBallLoop:
  231. ;
  232. ; Erase old image of ball in this page (at location from one more earlier).
  233. ;
  234.     mov    si,BLANK_OFFSET    ;point to blank image
  235.     mov    cx,[LastBallX+bx]
  236.     mov    dx,[LastBallY+bx]
  237.     call    DrawBall
  238. ;
  239. ; Set new last ball location.
  240. ;
  241.     mov    ax,[BallX+bx]
  242.     mov    [LastballX+bx],ax
  243.     mov    ax,[BallY+bx]
  244.     mov    [LastballY+bx],ax
  245. ;
  246. ; Change the ball movement values if it's time to do so.
  247. ;
  248.     dec    [BallRep+bx]        ;has current repeat factor run out?
  249.     jnz    MoveBall
  250.     mov    si,[BallControl+bx]    ;it's time to change movement values
  251.     lodsw                ;get new repeat factor from
  252.                     ; control string
  253.     and    ax,ax            ;at end of control string?
  254.     jnz    SetNewMove
  255.     mov    si,[BallControlString+bx]    ;reset control string
  256.     lodsw                ;get new repeat factor
  257. SetNewMove:
  258.     mov    [BallRep+bx],ax        ;set new movement repeat factor
  259.     lodsw                ;set new x movement increment
  260.     mov    [BallXInc+bx],ax
  261.     lodsw                ;set new y movement increment
  262.     mov    [BallYInc+bx],ax
  263.     mov    [BallControl+bx],si    ;save new control string pointer
  264. ;
  265. ; Move the ball.
  266. ;
  267. MoveBall:
  268.     mov    ax,[BallXInc+bx]
  269.     add    [BallX+bx],ax        ;move in x direction
  270.     mov    ax,[BallYInc+bx]
  271.     add    [BallY+bx],ax        ;move in y direction
  272. ;
  273. ; Draw ball at new location.
  274. ;
  275.     mov    si,BALL_OFFSET    ;point to ball's image
  276.     mov    cx,[BallX+bx]
  277.     mov    dx,[BallY+bx]
  278.     call    DrawBall
  279. ;
  280.     dec    bx
  281.     dec    bx
  282.     jns    EachBallLoop
  283. ;
  284. ; Pan and flip displayed page to the one we've been working on, as soon
  285. ; as leading edge of vertical sync comes around.
  286. ;
  287.     call    WaitVSync
  288. ;
  289. ; Perform whatever panning's in effect.
  290. ;
  291.     call    AdjustPanning
  292. ;
  293. ; Flip to new page by changing start address.
  294. ;
  295.     mov    ax,[CurrentPageOffset]
  296.     add    ax,[PanningStartOffset]
  297.     push    ax
  298.     SETREG    CRTC_INDEX, START_ADDRESS_LOW
  299.     mov    al,byte ptr [CurrentPageOffset+1]
  300.     pop    ax
  301.     mov    al,ah
  302.     SETREG    CRTC_INDEX, START_ADDRESS_HIGH
  303. ;
  304. ; Wait for sync again so the new start address has a chance
  305. ; to take effect.
  306. ;
  307.     call    WaitVSync
  308. ;
  309. ; Set horizontal panning now, just as new start address takes effect.
  310. ;
  311.     mov    al,[HPan]
  312.     mov    dx,STATUS_REGISTER_1
  313.     in    al,dx            ;reset ATC addressing to index reg
  314.     mov    al,[HPan]
  315.     SETREG    ATC_INDEX, HPELPAN
  316. ;
  317. ; Flip the page to draw to to the undisplayed page.
  318. ;
  319.     xor    [CurrentPage],1
  320.     jnz    IsPage1
  321.     mov    [CurrentPageOffset],PAGE0_OFFSET
  322.     jmp    short EndFlipPage
  323. IsPage1:
  324.     mov    [CurrentPageOffset],PAGE1_OFFSET
  325. EndFlipPage:
  326. ;
  327. ; Exit if a key's been hit.
  328. ;
  329.     mov    ah,1
  330.     int    16h
  331.     jnz    Done
  332.     jmp    BallAnimationLoop
  333. ;
  334. ; Finished, clear key, reset screen mode and exit.
  335. ;
  336. Done:
  337.     mov    ah,0    ;clear key
  338.     int    16h
  339. ;
  340.     mov    ax,3    ;reset to text mode
  341.     int    10h
  342. ;
  343.     mov    ah,4ch    ;exit to DOS
  344.     int    21h
  345. start    endp
  346. ;
  347. ; Routine to draw a ball-sized image to all planes, copying from
  348. ; offset SI in EGA memory to offset CX,DX (x,y) in EGA memory in
  349. ; the current page.
  350. ;
  351. DrawBall    proc    near
  352.     mov    ax,LOGICAL_SCREEN_WIDTH
  353.     mul    dx    ;offset of start of top image scan line
  354.     add    ax,cx    ;offset of upper left of image
  355.     add    ax,[CurrentPageOffset]    ;offset of start of page
  356.     mov    di,ax
  357.     mov    bp,BALL_HEIGHT
  358.     push    ds
  359.     push    es
  360.     pop    ds    ;move from EGA memory to EGA memory
  361. DrawBallLoop:
  362.     push    di
  363.     mov    cx,BALL_WIDTH
  364.     rep movsb    ;draw a scan line of image
  365.     pop    di
  366.     add    di,LOGICAL_SCREEN_WIDTH    ;point to next destination scan line
  367.     dec    bp
  368.     jnz    DrawBallLoop
  369.     pop    ds
  370.     ret
  371. DrawBall    endp
  372. ;
  373. ; Wait for the leading edge of vertical sync pulse.
  374. ;
  375. WaitVSync    proc    near
  376.     mov    dx,STATUS_REGISTER_1
  377. WaitNotVSyncLoop:
  378.     in    al,dx
  379.     and    al,VSYNC_MASK
  380.     jnz    WaitNotVSyncLoop
  381. WaitVSyncLoop:
  382.     in    al,dx
  383.     and    al,VSYNC_MASK
  384.     jz    WaitVSyncLoop
  385.     ret
  386. WaitVSync    endp
  387. ;
  388. ; Perform horizontal/vertical panning.
  389. ;
  390. AdjustPanning    proc    near
  391.     dec    [PanningRep]    ;time to get new panning values?
  392.     jnz    DoPan
  393.     mov    si,[PanningControl]    ;point to current location in
  394.                     ; panning control string
  395.     lodsw                ;get panning repeat factor
  396.     and    ax,ax            ;at end of panning control string?
  397.     jnz    SetnewPanValues
  398.     mov    si,offset PanningControlString    ;reset to start of string
  399.     lodsw                ;get panning repeat factor
  400. SetNewPanValues:
  401.     mov    [PanningRep],ax        ;set new panning repeat value
  402.     lodsw
  403.     mov    [PanningXInc],ax    ;horizontal panning value
  404.     lodsw
  405.     mov    [PanningYInc],ax    ;vertical panning value
  406.     mov    [PanningControl],si    ;save current location in panning
  407.                     ; control string
  408. ;
  409. ; Pan according to panning values.
  410. ;
  411. DoPan:
  412.     mov    ax,[PanningXInc]    ;horizontal panning
  413.     and    ax,ax
  414.     js    PanLeft            ;negative means pan left
  415.     jz    CheckVerticalPan
  416.     mov    al,[HPan]
  417.     inc    al            ;pan right; if pel pan reaches
  418.     cmp    al,8            ; 8, it's time to move to the
  419.     jb    SetHPan            ; next byte with a pel pan of 0
  420.     sub    al,al            ; and a start offset that's one
  421.     inc    [PanningStartOffset]    ; higher
  422.     jmp    short SetHPan
  423. PanLeft:
  424.     mov    al,[HPan]
  425.     dec    al            ;pan left; if pel pan reaches -1,
  426.     jns    SetHPan            ; it's time to move to the next
  427.     mov    al,7            ; byte with a pel pan of 7 and a
  428.     dec    [PanningStartOffset]    ; start offset that's one lower
  429. SetHPan:
  430.     mov    [HPan],al        ;save new pel pan value
  431. CheckVerticalPan:
  432.     mov    ax,[PanningYInc]    ;vertical panning
  433.     and    ax,ax
  434.     js    PanUp            ;negative means pan up
  435.     jz    EndPan
  436.     add    [PanningStartOffset],LOGICAL_SCREEN_WIDTH
  437.                     ;pan down by advancing the start
  438.                     ; address by a scan line
  439.     jmp    short EndPan
  440. PanUp:
  441.     sub    [PanningStartOffset],LOGICAL_SCREEN_WIDTH
  442.                     ;pan up by retarding the start
  443.                     ; address by a scan line
  444. EndPan:
  445.     ret
  446. ;
  447. ; Draw textured border around playfield that starts at DI.
  448. ;
  449. DrawBorder    proc    near
  450. ;
  451. ; Draw the left border.
  452. ;
  453.     push    di
  454.     mov    cx,LOGICAL_SCREEN_HEIGHT / 16
  455. DrawLeftBorderLoop:
  456.     mov    al,0ch        ;select red color for block
  457.     call    DrawBorderBlock
  458.     add    di,LOGICAL_SCREEN_WIDTH * 8
  459.     mov    al,0eh        ;select yellow color for block
  460.     call    DrawBorderBlock
  461.     add    di,LOGICAL_SCREEN_WIDTH * 8
  462.     loop    DrawLeftBorderLoop
  463.     pop    di
  464. ;
  465. ; Draw the left border.
  466. ;
  467.     push    di
  468.     add    di,LOGICAL_SCREEN_WIDTH - 1
  469.     mov    cx,LOGICAL_SCREEN_HEIGHT / 16
  470. DrawRightBorderLoop:
  471.     mov    al,0eh        ;select yellow color for block
  472.     call    DrawBorderBlock
  473.     add    di,LOGICAL_SCREEN_WIDTH * 8
  474.     mov    al,0ch        ;select red color for block
  475.     call    DrawBorderBlock
  476.     add    di,LOGICAL_SCREEN_WIDTH * 8
  477.     loop    DrawRightBorderLoop
  478.     pop    di
  479. ;
  480. ; Draw the top border.
  481. ;
  482.     push    di
  483.     mov    cx,(LOGICAL_SCREEN_WIDTH - 2) / 2
  484. DrawTopBorderLoop:
  485.     inc    di
  486.     mov    al,0eh        ;select yellow color for block
  487.     call    DrawBorderBlock
  488.     inc    di
  489.     mov    al,0ch        ;select red color for block
  490.     call    DrawBorderBlock
  491.     loop    DrawTopBorderLoop
  492.     pop    di
  493. ;
  494. ; Draw the bottom border.
  495. ;
  496.     add    di,(LOGICAL_SCREEN_HEIGHT - 8) * LOGICAL_SCREEN_WIDTH
  497.     mov    cx,(LOGICAL_SCREEN_WIDTH - 2) / 2
  498. DrawBottomBorderLoop:
  499.     inc    di
  500.     mov    al,0ch        ;select red color for block
  501.     call    DrawBorderBlock
  502.     inc    di
  503.     mov    al,0eh        ;select yellow color for block
  504.     call    DrawBorderBlock
  505.     loop    DrawBottomBorderLoop
  506.     ret
  507. DrawBorder    endp
  508. ;
  509. ; Draws an 8x8 border block in color in AL at location DI.
  510. ; DI preserved.
  511. ;
  512. DrawBorderBlock    proc    near
  513.     push    di
  514.     SETREG    TS_INDEX, MAP_MASK
  515.     mov    al,0ffh
  516.     rept 8
  517.     stosb
  518.     add    di,LOGICAL_SCREEN_WIDTH - 1
  519.     endm
  520.     pop    di
  521.     ret
  522. DrawBorderBlock    endp
  523. AdjustPanning    endp
  524. cseg    ends
  525.     end    start
  526.  
  527.